﻿//==============================================================================
// File: TabMenu.cs
// Created: 2010-05-28
// Author: Piotr Włodek, Arek Świerczek
//==============================================================================
// This file is a part of MAMMOTH project.
// Copyright (C) 2010 AGH University of Science and Technology, Krakow.
// https://caribou.iisg.agh.edu.pl/trac/mammoth
//
// Mammoth is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Mammoth is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Mammoth. If not, see http://www.gnu.org/licenses/.
//==============================================================================

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfRcp.Controls
{
    public class TabMenu : TabControl
    {
        public static readonly RoutedUICommand CloseCommand = new RoutedUICommand("Close", "TabMenu.Items.Close", typeof(TabMenu));
        public static readonly RoutedUICommand CloseAllCommand = new RoutedUICommand("Close All", "TabMenu.Items.CloseAll", typeof(TabMenu));
        public static readonly RoutedUICommand CloseAllButThisCommand = new RoutedUICommand("Close All But This", "TabMenu.Items.CloseAllButThis", typeof(TabMenu));

        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(TabMenu), new PropertyMetadata(new CornerRadius(0.0)));

        public static readonly DependencyProperty IsSortableProperty =
            DependencyProperty.Register("IsSortable", typeof(bool), typeof(TabMenu), new UIPropertyMetadata(true));

        public static RoutedEvent VisibilityChangedEvent = EventManager.RegisterRoutedEvent("VisibilityChanged",
                                                                                            RoutingStrategy.Bubble, typeof(VisibilityChangedRoutedEventHandler), typeof(TabMenu));

        static TabMenu()
        {
            // This OverrideMetadata call tells the system that this element wants
            // to provide a style that is different than its base class
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TabMenu),
                                                     new FrameworkPropertyMetadata(typeof(TabMenu)));

            // This call registers callback for the VisibilityProperty dependency property
            VisibilityProperty.OverrideMetadata(typeof(TabMenu), new PropertyMetadata(OnVisibilityChanged));
        }

        public TabMenu()
        {
            CommandBindings.Add(new CommandBinding(CloseCommand,
                                                   ExecuteCloseCommand, CanExecuteCloseCommand));

            CommandBindings.Add(new CommandBinding(CloseAllCommand,
                                                   ExecuteCloseAllCommand, CanExecuteCloseAllCommand));

            CommandBindings.Add(new CommandBinding(CloseAllButThisCommand,
                                                   ExecuteCloseAllButThisCommand, CanExecuteCloseAllButThisCommand));
        }

        public event VisibilityChangedRoutedEventHandler VisibilityChanged
        {
            add { AddHandler(VisibilityChangedEvent, value); }
            remove { RemoveHandler(VisibilityChangedEvent, value); }
        }

        protected virtual void OnVisibilityChanged(VisibilityChangedRoutedEventArgs e)
        {
            e.RoutedEvent = VisibilityChangedEvent;
            RaiseEvent(e);
        }

        private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var tabMenu = (TabMenu)d;
            tabMenu.OnVisibilityChanged(new VisibilityChangedRoutedEventArgs((Visibility)e.NewValue));
        }

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public bool IsSortable
        {
            get { return (bool)GetValue(IsSortableProperty); }
            set { SetValue(IsSortableProperty, value); }
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is TabMenuItem;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TabMenuItem();
        }

        private void ExecuteCloseAllCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var items = new List<TabMenuItem>();
            foreach (TabMenuItem item in Items)
            {
                items.Add(item);
            }

            foreach (var item in items)
            {
                item.CloseTabMenuItem();
            }
        }

        private void CanExecuteCloseAllCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = false;
            foreach (TabMenuItem item in Items)
            {
                if (item.IsCloseable)
                {
                    e.CanExecute = true;
                    break;
                }
            }
        }

        private void ExecuteCloseAllButThisCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var items = new List<TabMenuItem>();
            foreach (TabMenuItem item in Items)
            {
                if (SelectedItem != item)
                {
                    items.Add(item); 
                }
            }

            foreach (var item in items)
            {
                item.CloseTabMenuItem();
            }
        }

        private void CanExecuteCloseAllButThisCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = false;
            foreach (TabMenuItem item in Items)
            {
                if (item.IsCloseable)
                {
                    e.CanExecute = true;
                    break;
                }
            }
        }

        private void ExecuteCloseCommand(object sender, ExecutedRoutedEventArgs e)
        {
            ((TabMenuItem) SelectedItem).CloseTabMenuItem();
        }

        private void CanExecuteCloseCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ((TabMenuItem) SelectedItem).IsCloseable;
        }
    }

    public delegate void VisibilityChangedRoutedEventHandler(object sender, VisibilityChangedRoutedEventArgs e);

    public class VisibilityChangedRoutedEventArgs : RoutedEventArgs
    {
        private readonly Visibility m_Visibility;

        public VisibilityChangedRoutedEventArgs(Visibility visibility)
        {
            m_Visibility = visibility;
        }

        public Visibility Visibility
        {
            get { return m_Visibility; }
        }
    }
}